package com.admin.education.services.Implements;

import com.admin.education.common.exceptions.ResourceNotFoundException;
import com.admin.education.dataTransferObject.PageResponse;
import com.admin.education.dataTransferObject.ServicesExcuteResult;
import com.admin.education.dataTransferObject.categorys.CategorysTransfer;
import com.admin.education.dataTransferObject.circles.CirclesTransfer;
import com.admin.education.dataTransferObject.circles.CommentsTransfer;
import com.admin.education.dataTransferObject.circles.Mapper.CirclesMapper;
import com.admin.education.dataTransferObject.circles.Mapper.CommentsMapper;
import com.admin.education.dataTransferObject.circles.Request.CreateCirclesRequest;
import com.admin.education.dataTransferObject.circles.Request.QueryCirclesRequest;
import com.admin.education.dataTransferObject.comments.Request.CreateCommentsRequest;
import com.admin.education.domain.event.CreateUserRecordEvent;
import com.admin.education.models.*;
import com.admin.education.repositories.*;
import com.admin.education.services.Interfaces.ICirclesService;
import com.google.common.eventbus.EventBus;
import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import javax.validation.Valid;
import java.awt.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class CirclesService implements ICirclesService {
    private QCircles qCircles;
    private QCategorys qCategorys;
    private QUserInformation qUserInformation;
    private QAdmirers qAdmirers;
    @Autowired
    private CirclesRepository circlesRepository;
    @Autowired
    private CirclesMapper circlesMapper;
    @Autowired
    private CommentsMapper commentsMapper;
    @Autowired
    private CategorysRepository categorysRepository;
    @Autowired
    private UserInformationRepository userInformationRepository;
    @Autowired
    private PicturesRepository picturesRepository;
    @Autowired
    private UserRecordRepository userRecordRepository;
    @Autowired
    private CommentsRepository commentsRepository;
    @Autowired
    private EventBus eventBus;
    private QComments qComments;
    @Autowired
    private AdmirersRepository admirersRepository;
    public CirclesService() {
        qCircles = QCircles.circles;
        qCategorys = QCategorys.categorys;
        qUserInformation =QUserInformation.userInformation;
        qComments = QComments.comments;
        qAdmirers =QAdmirers.admirers;
    }

    @Override
    public ServicesExcuteResult createCircle(long userInformationId, @Valid CreateCirclesRequest createCirclesRequest) {
        ServicesExcuteResult servicesExcuteResult = new ServicesExcuteResult();
        Circles circles = this.circlesMapper.mapFrom(createCirclesRequest);

        Categorys categorys = categorysRepository.selectFrom(qCategorys).where(qCategorys.id.eq(createCirclesRequest.getCategoryId())).fetchOne();

        if (null == categorys) {
            servicesExcuteResult.setErrorMessage("分类不存在");
            return servicesExcuteResult;
        }

        circles.setCategorys(new ArrayList<>());
        circles.getCategorys().add(categorys);

        categorys.getCircles().add(circles);

        UserInformation userInformation = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(userInformationId)).fetchFirst();
        if(null==userInformation){
            servicesExcuteResult.setErrorMessage("用户不存在");
            return servicesExcuteResult;
        }
        circles.setUserInformationId(userInformationId);
        this.circlesRepository.persist(circles);
        this.picturesRepository.persist(circles.getPirtures());

        this.categorysRepository.merge(categorys);

        CreateUserRecordEvent createUserRecordEvent = new CreateUserRecordEvent();
        createUserRecordEvent.setUserInformationId(userInformationId);
        createUserRecordEvent.setRecord("发起了图片分享");

        this.eventBus.post(createUserRecordEvent);
        servicesExcuteResult.setSuccess(true);
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<PageResponse<CirclesTransfer>> queryCircles(@Valid QueryCirclesRequest circlesRequest) {
        ServicesExcuteResult<PageResponse<CirclesTransfer>> servicesExcuteResult =new ServicesExcuteResult<>();

        JPAQuery<Circles> circlesJPAQuery = this.circlesRepository.selectFrom(qCircles);
        if(null!=circlesRequest.getCategoryId()){
            circlesJPAQuery = circlesJPAQuery.innerJoin(qCircles.categorys,qCategorys).where(qCategorys.id.eq(circlesRequest.getCategoryId())).distinct();
        }

        long totalCount = circlesJPAQuery.fetchCount();
        circlesJPAQuery = circlesJPAQuery.orderBy(qCircles.createTime.desc())
                .offset((circlesRequest.getPageIndex()-1)*circlesRequest.getPageSize()).limit(circlesRequest.getPageSize());

        List<Circles> circles = circlesJPAQuery.fetch();

        List<CirclesTransfer> circlesTransfers = this.circlesMapper.mapFrom(circles);
        PageResponse<CirclesTransfer> circlesTransferPageResponse = new PageResponse<>(circlesRequest.getPageSize(),circlesRequest.getPageIndex(),(int)totalCount,circlesTransfers);

        servicesExcuteResult.setData(circlesTransferPageResponse);
        servicesExcuteResult.setSuccess(true);

        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<CirclesTransfer> queryCircles(long criclesId) throws ResourceNotFoundException {
        ServicesExcuteResult<CirclesTransfer> servicesExcuteResult = new ServicesExcuteResult();

        JPAQuery<Circles> circlesTransferJPAQuery = this.circlesRepository.selectFrom(qCircles).where(qCircles.id.eq(criclesId));
        if(0!=circlesTransferJPAQuery.fetchCount()){
            Circles circles = circlesTransferJPAQuery.fetchOne();

            CirclesTransfer circlesTransfer = this.circlesMapper .mapFrom(circles);
            circlesTransfer.setAdmirerSize((int)this.admirersRepository.selectFrom(qAdmirers).where(qAdmirers.circles.id.eq(criclesId)).fetchCount());
            servicesExcuteResult.setData(circlesTransfer);
            servicesExcuteResult.setSuccess(true);
        }
        else {
            throw new ResourceNotFoundException("图片文章不存在");
        }
        return servicesExcuteResult;
    }
    @Override
    public ServicesExcuteResult createComments(long circlesId, long userInformationId, @Valid CreateCommentsRequest createCommentsRequest) throws ResourceNotFoundException {
        ServicesExcuteResult servicesExcuteResult = new ServicesExcuteResult();

        JPAQuery<Circles> circlesJPAQuery = this.circlesRepository.selectFrom(qCircles).where(qCircles.id.eq(circlesId));

        JPAQuery<UserInformation> userInformationJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(userInformationId));
        if (0 == userInformationJPAQuery.fetchCount()) {
            throw new ResourceNotFoundException("用戶不存在");
        }
        if (0 != circlesJPAQuery.fetchCount()) {
            Circles circles = circlesJPAQuery.fetchFirst();
            UserInformation userInformation = new UserInformation();

            Comments comments = new Comments();
            comments.setContent(createCommentsRequest.getContent());
            comments.setCreateTime(new Date());
            comments.setCircles(circles);
            comments.setUserInformationId(userInformationId);

            this.commentsRepository.persist(comments);

            CreateUserRecordEvent createUserRecordEvent = new CreateUserRecordEvent();
            createUserRecordEvent.setUserInformationId(userInformationId);
            createUserRecordEvent.setRecord("评论了"+circles.getTitle());

            this.eventBus.post(createUserRecordEvent);
            servicesExcuteResult.setSuccess(true);
        } else {
            throw new ResourceNotFoundException("文章不存在");
        }

        return servicesExcuteResult;
    }
    public ServicesExcuteResult<List<CommentsTransfer>> queryComments(long articlesId) {
        ServicesExcuteResult<List<CommentsTransfer>> servicesExcuteResult = new ServicesExcuteResult<>();

        JPAQuery<Comments> commentsJPAQuery = this.commentsRepository.selectFrom(qComments).where(qComments.circles.id.eq(articlesId)).limit(100);

        servicesExcuteResult.setData(this.commentsMapper.mapFrom(commentsJPAQuery.fetch()));
        servicesExcuteResult.setSuccess(true);
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult createAdmirer(long circlesId, long userInformationid) throws ResourceNotFoundException {
        ServicesExcuteResult servicesExcuteResult = new ServicesExcuteResult();

        JPAQuery<Circles> circlesJPAQuery = this.circlesRepository.selectFrom(qCircles).where(qCircles.id.eq(circlesId));

        JPAQuery<UserInformation> userInformationJPAQuery = this.userInformationRepository.selectFrom(qUserInformation).where(qUserInformation.id.eq(userInformationid));
        if (0 == userInformationJPAQuery.fetchCount()) {
            throw new ResourceNotFoundException("用戶不存在");
        }
        if (0 != circlesJPAQuery.fetchCount()) {
            UserInformation userInformation = userInformationJPAQuery.fetchFirst();
            Admirers admirers = new Admirers();
            Circles circles = circlesJPAQuery.fetchFirst();
            if(circles.getAdmirers().stream().anyMatch(p->p.getUserInformationId()==userInformation.getId()))
            {
                servicesExcuteResult.setErrorMessage("不能重复点赞");
                return servicesExcuteResult;
            }
            admirers.setCircles(circles);
            admirers.setUserInformationId(userInformationid);
            admirers.setCreateTime(new Date());

            CreateUserRecordEvent createUserRecordEvent = new CreateUserRecordEvent();
            createUserRecordEvent.setUserInformationId(userInformationid);
            createUserRecordEvent.setRecord("点赞了"+circles.getTitle());

            this.eventBus.post(createUserRecordEvent);

            this.admirersRepository.persist(admirers);
            servicesExcuteResult.setSuccess(true);
        } else {
            throw new ResourceNotFoundException("文章不存在");
        }

        return servicesExcuteResult;
    }

}
